package yang.itcode.service.impl;

import cn.hutool.json.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yang.itcode.exception.BusinessException;
import yang.itcode.mapper.OtherCostMapper;
import yang.itcode.mapper.ProfitMapper;
import yang.itcode.model.pojo.OtherCost;
import yang.itcode.model.pojo.Profit;
import yang.itcode.service.OtherCostService;
import yang.itcode.utils.ThreadUtil;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;

import static yang.itcode.constant.ErrorConstant.*;
import static yang.itcode.constant.OptionConstant.PROFIT_OPTION_OTHER;

@Service
public class OtherCostServiceImpl implements OtherCostService {

    @Autowired
    private OtherCostMapper otherCostMapper;
    @Autowired
    private ProfitMapper profitMapper;

    @Override
    @Transactional
    public boolean addOtherCost(JSONObject obj) {
        String name = obj.getStr("name");
        BigDecimal cost = obj.getBigDecimal("cost");
        String note = obj.getStr("note");
        LocalDate date = obj.get("date", LocalDate.class);
        if (name == null || name.isEmpty() || cost == null || date == null) {
            throw new BusinessException(OTHER_COST_PARAM_EXCEPTION_CODE, OTHER_COST_PARAM_EXCEPTION_MESSAGE);
        }
        if (cost.compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException(OTHER_COST_PARAM_EXCEPTION_CODE, "费用不能小于0");
        }
        Integer userId = ThreadUtil.getCurrentId();
        OtherCost oc = new OtherCost();
        oc.setName(name);
        oc.setCost(cost);
        oc.setNote(note);
        oc.setDate(date);
        oc.setStatus(1);
        oc.setCreateUserId(userId);
        oc.setUpdateUserId(userId);
        if (otherCostMapper.insert(oc) != 1) {
            throw new BusinessException(OTHER_COST_ADD_EXCEPTION_CODE, OTHER_COST_ADD_EXCEPTION_MESSAGE);
        }
        // 查询插入的记录的ID
        JSONObject condition = new JSONObject();
        condition.set("orderBy", "create_time");
        condition.set("sortOrder", "desc");
        condition.set("status", 1);
        PageHelper.startPage(1, 1);
        List<JSONObject> list = otherCostMapper.selectOtherCostView(condition);
        if (list.isEmpty()) {
            throw new BusinessException(OTHER_COST_ADD_EXCEPTION_CODE, OTHER_COST_ADD_EXCEPTION_MESSAGE);
        }
        JSONObject lastRecord = list.get(0);
        // 记入损益
        Profit profit = new Profit();
        profit.setOperationType(PROFIT_OPTION_OTHER);
        profit.setValue(cost.negate());
        profit.setDate(date);
        profit.setNote("其他成本扣减利润，其他成本ID：" + lastRecord.getInt("id"));
        profit.setRelatedId(lastRecord.getInt("id"));
        profit.setCreateUserId(userId);
        profit.setUpdateUserId(userId);
        if (profitMapper.insert(profit) != 1) {
            throw new BusinessException(OTHER_COST_ADD_EXCEPTION_CODE, OTHER_COST_ADD_EXCEPTION_MESSAGE);
        }
        return true;
    }

    @Override
    public PageInfo<JSONObject> getOtherCostList(Integer pageNum, Integer pageSize, JSONObject condition) {
        if (condition == null) condition = new JSONObject();
        condition.set("status", 1);
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        return new PageInfo<>(otherCostMapper.selectOtherCostView(condition));
    }

    @Override
    public JSONObject getOtherCostDetail(Integer id) {
        JSONObject condition = new JSONObject();
        condition.set("id", id);
        condition.set("status", 1);
        List<JSONObject> list = otherCostMapper.selectOtherCostView(condition);
        if (list.isEmpty()) {
            throw new BusinessException(OTHER_COST_NOT_EXIST_EXCEPTION_CODE, OTHER_COST_NOT_EXIST_EXCEPTION_MESSAGE);
        }
        return list.get(0);
    }

    @Override
    @Transactional
    public boolean updateOtherCost(JSONObject obj) {
        Integer id = obj.getInt("id");
        String name = obj.getStr("name");
        BigDecimal cost = obj.getBigDecimal("cost");
        LocalDate date = obj.get("date", LocalDate.class);
        String note = obj.getStr("note");
        if (id == null || name == null || name.isEmpty() || cost == null || date == null) {
            throw new BusinessException(OTHER_COST_PARAM_EXCEPTION_CODE, OTHER_COST_PARAM_EXCEPTION_MESSAGE);
        }
        if (cost.compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException(OTHER_COST_PARAM_EXCEPTION_CODE, "费用不能小于0");
        }
        OtherCost old = otherCostMapper.selectById(id);
        if (old == null || old.getStatus() == null || old.getStatus() != 1) {
            throw new BusinessException(OTHER_COST_NOT_EXIST_EXCEPTION_CODE, OTHER_COST_NOT_EXIST_EXCEPTION_MESSAGE);
        }
        Integer userId = ThreadUtil.getCurrentId();
        OtherCost oc = new OtherCost();
        oc.setId(id);
        oc.setName(name);
        oc.setCost(cost);
        oc.setNote(note);
        oc.setDate(date);
        oc.setUpdateUserId(userId);
        if (otherCostMapper.update(oc) != 1) {
            throw new BusinessException(OTHER_COST_UPDATE_EXCEPTION_CODE, OTHER_COST_UPDATE_EXCEPTION_MESSAGE);
        }
        JSONObject condition = new JSONObject();
        condition.set("relatedId", id);
        condition.set("operationType", PROFIT_OPTION_OTHER);
        condition.set("status", 1);
        List<Profit> list = profitMapper.selectByCondition(condition);
        if (list.isEmpty()) {
            throw new BusinessException(OTHER_COST_UPDATE_EXCEPTION_CODE, OTHER_COST_UPDATE_EXCEPTION_MESSAGE);
        }
        // 更新损益记录
        Profit profit = list.get(0);
        profit.setOperationType(PROFIT_OPTION_OTHER);
        profit.setValue(cost.negate());
        profit.setDate(date);
        profit.setNote("其他成本扣减利润，其他成本ID：" + id);
        profit.setRelatedId(id);
        profit.setUpdateUserId(userId);
        if (profitMapper.update(profit) != 1) {
            throw new BusinessException(OTHER_COST_UPDATE_EXCEPTION_CODE, OTHER_COST_UPDATE_EXCEPTION_MESSAGE);
        }
        return true;
    }

    @Override
    @Transactional
    public boolean deleteOtherCost(Integer id) {
        OtherCost old = otherCostMapper.selectById(id);
        if (old == null || old.getStatus() == null || old.getStatus() != 1) {
            throw new BusinessException(OTHER_COST_NOT_EXIST_EXCEPTION_CODE, OTHER_COST_NOT_EXIST_EXCEPTION_MESSAGE);
        }
        Integer userId = ThreadUtil.getCurrentId();
        OtherCost oc = new OtherCost();
        oc.setId(id);
        oc.setStatus(0);
        oc.setUpdateUserId(userId);
        if (otherCostMapper.update(oc) != 1) {
            throw new BusinessException(OTHER_COST_DELETE_EXCEPTION_CODE, OTHER_COST_DELETE_EXCEPTION_MESSAGE);
        }
        JSONObject condition = new JSONObject();
        condition.set("relatedId", id);
        condition.set("operationType", PROFIT_OPTION_OTHER);
        condition.set("status", 1);
        List<Profit> list = profitMapper.selectByCondition(condition);
        if (list.isEmpty()) {
            throw new BusinessException(OTHER_COST_UPDATE_EXCEPTION_CODE, OTHER_COST_UPDATE_EXCEPTION_MESSAGE);
        }
        // 删除损益记录
        Profit profit = list.get(0);
        profit.setRelatedId(id);
        profit.setStatus(0);
        profit.setUpdateUserId(userId);
        if (profitMapper.update(profit) != 1) {
            throw new BusinessException(OTHER_COST_DELETE_EXCEPTION_CODE, OTHER_COST_DELETE_EXCEPTION_MESSAGE);
        }
        return true;
    }
}
